using System;
using System.Collections.Generic;
using CoreLibrary.Messaging.Sql;
using CoreLibrary.Service;

namespace CoreLibrary.Messaging.Store {

    public interface IMessageStore : IService{

        int CountTotalMessage();
        int CountMessage(ListMessageQuery query);
        int CountEnqueuedMessage();
        int CountProcessingMessage();

        Message GetMessage(string messageId);
        MessageStatus? GetMessageStatus(string messageId);
        List<Message> ListMessages(ListMessageQuery query);

        void ListMessages  (ListMessageQuery query, Action<Message> callback);
        void InsertMessage (Message message);

        /// <summary>
        /// Update the status of a message by id.
        /// </summary>
        /// <param name="messageId"></param>
        /// <param name="newStatus"></param>
        /// <param name="fault"></param>
        /// <param name="retry"></param>
        /// <param name="dateScheduled"></param>
        /// <returns>true if a message was updated, false otherwise which usually happens when the target message doesn't exist. </returns>
        bool UpdateMessageStatus(string messageId,
                                 MessageStatus newStatus,
                                 string fault,
                                 int retry,
                                 DateTime dateScheduled);

        /// <summary>
        /// Compare and update the status of a message by id and status.
        /// </summary>
        /// <param name="messageId"></param>
        /// <param name="expectedStatus"></param>
        /// <param name="newStatus"></param>
        /// <param name="fault"></param>
        /// <param name="retry"></param>
        /// <param name="dateScheduled"></param>
        /// <returns>true if a message was updated, false otherwise which usually happens when the target message doesn't exist or is updated by another thread. </returns>
        bool CompareAndUpdateMessageStatus(string messageId,
                                           MessageStatus expectedStatus,
                                           MessageStatus newStatus,
                                           string fault,
                                           int retry,
                                           DateTime dateScheduled);

        /// <summary>
        /// Delete a message by id.
        /// </summary>
        /// <param name="messageId"></param>
        /// <returns>true if a message was deleted, false otherwise which usually happens when the target message doesn't exist. </returns>
        bool RemoveMessage(string messageId);

    }

}